package cc.rengu.oltp.service.realize.impl;

import cc.rengu.oltp.service.common.constant.AppConfigConstant;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.model.PasswordInfo;
import cc.rengu.oltp.service.realize.SafeKeyBoardService;
import cc.rengu.oltp.utility.util.MD5Util;
import cc.rengu.oltp.utility.util.StringUtil;
import cc.rengu.oltp.utility.util.XmlConfigUtil;
import cc.rengu.utility.log.RgLog;
import cc.rengu.utility.log.RgLogger;

import java.lang.reflect.Method;

/**
 * 密码键盘调用实现类
 * Created by wangcheng on 2021/3/25 16:08
 */
public class SafeKeyBoardServiceImpl implements SafeKeyBoardService {
    RgLogger rglog = RgLog.getLogger(this.getClass().getName());
    private boolean apiCallFlag = false;
    private Class clasz;
    private Object methodInstance;

    public SafeKeyBoardServiceImpl() throws Exception {
        String safeKeyBoardServiceImpl = XmlConfigUtil.getXmlConfigCacheKeyValue(AppConfigConstant.APPLICATION_CONF_NODE, AppConfigConstant.SAFE_KEY_BOARD_SERVICE_IMPL);
        String DEFAULT_IMPL = "cc.rengu.oltp.service.realize.impl.SafeKeyBoardServiceImpl";
        if (!StringUtil.isEmptyOrNull(safeKeyBoardServiceImpl) && !DEFAULT_IMPL.equals(safeKeyBoardServiceImpl.trim())) {
            apiCallFlag = true;
            clasz = Class.forName(safeKeyBoardServiceImpl.trim());
            methodInstance = clasz.newInstance();
        }
    }

    @Override
    public String encryptPassword(String instId, String channelType, PasswordInfo passwordInfo, Object extraPasswordInfo) throws Exception {
        if (apiCallFlag) {
            Method encryptPasswordMethod = clasz.getMethod("encryptPassword", String.class, String.class, PasswordInfo.class, Object.class);
            return (String) encryptPasswordMethod.invoke(methodInstance, instId, channelType, passwordInfo, extraPasswordInfo);
        } else {
            if (AppParamConstant.DEFAULT_ENV.equals(AppParamConstant.APPLICATION_ENV)) {
                rglog.error("未配置密码键盘调用实现类，使用系统简单的加密方式，且勿带上生产!");
                if (StringUtil.isEmptyOrNull(passwordInfo.getPasswordValue())) {
                    rglog.error("未上送密码字段信息，加密失败!");
                    throw new Exception("未上送密码字段信息，加密失败!!");
                } else {
                    return passwordInfo.getPasswordValue().trim();
                }
            } else {
                rglog.error("未配置密码键盘调用实现类或者配置的实现类不存在，请检查applicationConfig.xml中的配置!");
                throw new Exception("未配置密码键盘调用实现类或者配置的实现类不存在!");
            }
        }
    }

    @Override
    public boolean verifyPassword(String instId, String channelType, String passwordVerifyValue, PasswordInfo passwordInfo, Object extraPasswordInfo) throws Exception {
        if (apiCallFlag) {
            Method verifyPasswordMethod = clasz.getMethod("verifyPassword", String.class, String.class, String.class, PasswordInfo.class, Object.class);
            return (boolean) verifyPasswordMethod.invoke(methodInstance, instId, channelType, passwordVerifyValue, passwordInfo, extraPasswordInfo);
        } else {
            if (AppParamConstant.DEFAULT_ENV.equals(AppParamConstant.APPLICATION_ENV)) {
                rglog.error("未配置密码键盘调用实现类，使用系统简单的密码校验方式，且勿带上生产!");
                return passwordInfo.getPasswordValue().equalsIgnoreCase(passwordVerifyValue);
            } else {
                rglog.error("未配置密码键盘调用实现类或者配置的实现类不存在，请检查applicationConfig.xml中的配置!");
                throw new Exception("未配置密码键盘调用实现类或者配置的实现类不存在!");
            }
        }
    }

    @Override
    public String transferPassword(String instId, String channelType, String passwordCipherValue, PasswordInfo passwordInfo, Object extraPasswordInfo) throws Exception {
        if (apiCallFlag) {
            Method transferPasswordMethod = clasz.getMethod("transferPassword", String.class, String.class, String.class, PasswordInfo.class, Object.class);
            return (String) transferPasswordMethod.invoke(methodInstance, instId, channelType, passwordCipherValue, passwordInfo, extraPasswordInfo);
        } else {
            if (AppParamConstant.DEFAULT_ENV.equals(AppParamConstant.APPLICATION_ENV)) {
                rglog.error("未配置密码键盘调用实现类，使用系统简单的转加密方式，且勿带上生产!");
                String encryptData = instId.trim() + passwordInfo.getTargetUserId().trim() + passwordCipherValue.trim();
                return MD5Util.generateSignString(encryptData);
            } else {
                rglog.error("未配置密码键盘调用实现类或者配置的实现类不存在，请检查applicationConfig.xml中的配置!");
                throw new Exception("未配置密码键盘调用实现类或者配置的实现类不存在!");
            }
        }
    }
}
